import string
import scipy
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import os
import sys
import glob
import cPickle
import skimage
sys.path.append(os.path.abspath("C:\Users\Scherer Lab E\Documents\GitHub\Python_Data_Analysis"))
import common_functions as cf
import passing_event_functions as pef
import trackpy_helper_functions as tphf
import seaborn as sns
Load the database
store = pd.HDFStore("K:\Pat's_Projects\ParticleTrajectoryData\passing_event_data_trackpy.h5", mode='r')
Create a giant dataframe that has all the data in it. Note that track id names are reduntact between different experiments.
keys = store.index['key']
giant_df = pd.DataFrame()
for key in keys[:]:
df = store.get(key).copy()
giant_df = giant_df.append(df, ignore_index=True)
df = giant_df.copy()
df = df.dropna(axis=0, subset=['del_theta'])
df = df[df['track id'] < df['theta_nn_id']]
df = df.query('-20 < del_theta < 20')
g = sns.JointGrid(x='del_theta', y='del_r', data=df, size=7, ratio=2)
g.plot_joint(plt.scatter, s=1.5, marker='.', alpha=0.4)
g.ax_marg_x.hist(df.del_theta, bins=100)
g.ax_marg_y.hist(df.del_r, bins=100, orientation='horizontal')
g.set_axis_labels(xlabel=r'$\Delta \theta$ (degrees)', ylabel=r'$\Delta$r (pixels)')
g.ax_marg_x.set_title('All Mosaic Data')
plt.setp(g.ax_marg_x.get_yticklabels(), visible=True)
plt.setp(g.ax_marg_y.get_xticklabels(), visible=True)
plt.show()
This is the familiar $\Delta \theta$ and $\Delta$r plot we have seen before except this time there is no conditional probability for "passing event trajectories". There is a symmetry in these graphs which is 180 degrees rotationally symmetric because I am not selecting for particles i < j. So for every point $\Delta \theta$ and $\Delta$r point there will be another one with exactly the opposite sign for each.
The idea for plotting this scatter plot was to get a feel for how many counts do I have in the passing region and hopefully better inform me on how to properly label passing events. Looking at $\Delta \theta = 0$ tells me the number of events that I have.
One of the ideas I had to properly labeling passing events is instead of selecting a box in $\Delta \theta$ and $\Delta$r for finding passing events is to find trajectories where $\Delta \theta$ goes from being negative to positive when looking at the relative trajectories of a pair. I think this is the most similar to the way events were found in the Half Nanoplate Analysis. There will be some things to consider. I suspect that there will be more noise in the transition region than in the half nanoplate data because I think it is possible for a particle to cross from negative to positive and still not pass all the way or spend a couple of frames oscillating between negative and positive. The other obvious thing to watch out for is the switching from positive to negative at $\Delta \theta$ approaching -180 degrees.
df = giant_df.copy()
#df = df[df['track id'] < df['theta_nn_id']]
# Have to rotate the coordinates in theta to make them align with a
# normal unit circle.
df['theta'] = (df['theta'] + 90) % 360
df = df.query('-20 < del_theta < 20')
df = df.dropna(axis=0, subset=['del_theta'])
g = sns.JointGrid(x='del_theta', y='theta', data=df, size=7, ratio=2)
g.plot_joint(plt.scatter, s=1.5, marker='.')
g.ax_marg_x.hist(df.del_theta, bins=100)
g.ax_marg_y.hist(df.theta, bins=100, orientation='horizontal')
g.set_axis_labels(xlabel=r'$\Delta \theta$ (degrees)', ylabel=r'$\theta$ (degrees)')
plt.setp(g.ax_marg_x.get_yticklabels(), visible=True)
plt.setp(g.ax_marg_y.get_xticklabels(), visible=True)
plt.show()
The thought of why to plot $\theta$ vs $\Delta \theta$ is to try to answer the question of where there passing events are occuring around the ring. I have suspected that the passing events occur where the optical binding site transitions from overlapping the ring trap to being perpendicular to the ring trap, i.e. the optical binding interaction assists particles to escape the trap and get passed by another. In this representation we look along where $\Delta \theta = 0$ and see where we see points. In the graph above you can see points mostly at 140 degrees and 320 degrees while there are no points at 70 degrees and 240 degrees.
This is opposite of what I thought was going to happen. When the particle is at 90 degrees and 270 degrees the optical binding zones are perpendicular to the ring trap because the polarization is horizontal in the lab frame. And because there is high number of points at 140 and 320 degrees that means that the passing events are ocurring when the optical binding sites go from not overlapping the ring trap to overlapping. It seems my proposed mechanism of the optical binding potentials helping the particles leave the trap might not be correct.
I double checked that the degrees were correct and that the polarization is horizontal in the lab frame (by comparing nearest neighbors distributions in parallel and perpendicular).
Curtis had the question about if when the particles pass if they act like a rotating rigid body. To me the only way that would make sense is if the particles is interacting in optical binding or near field as they pass. In an attempt to answer this question I plotted the separtion of particles vs $\Delta \theta$. When two particles are involved in a passing event they go through $\Delta \theta = 0$. By plotting a scatter plot of the cartesian separations of the particles vs $\Delta \theta$ then we can inform ourselves if the particles pass eachother through optical binding or nearfield interaction.
Note: this doesn't answer Curtis' question directly. Curtis is asking as a pair of particles pass eachother do they maintain the same distance. Not if on average do passing particles arrange themselves at a specific separation.
def cart_seps_aligned_to_theta_nn_num(dataframe):
df = dataframe.copy()
df_frame_track_nn_index = df.set_index(['frame', 'track id', 'nn_id'])
indicies_to_grab = df[['frame', 'track id', 'theta_nn_id']].values
zipped_index = zip(indicies_to_grab[:,0], indicies_to_grab[:,1], indicies_to_grab[:,2])
aligned_nn_sep = df_frame_track_nn_index.ix[zipped_index].reset_index()
aligned_nn_sep = aligned_nn_sep['nn_dist']
df['cart_sep'] = aligned_nn_sep
return df
keys = store.index['key']
cart_sep_agg = pd.DataFrame()
for key in keys[:]:
df = store.get(key).copy()
df = cart_seps_aligned_to_theta_nn_num(df)
df = df[['del_theta', 'cart_sep']]
cart_sep_agg = cart_sep_agg.append(df, ignore_index=True)
df = cart_sep_agg.copy()
#df = df[df['track id'] < df['theta_nn_id']]
# Have to rotate the coordinates in theta to make them align with a
# normal unit circle.
#df['theta'] = (df['theta'] + 90) % 360
df = df.query('-20 < del_theta < 20')
df = df.dropna(axis=0, subset=['del_theta'])
df['cart_sep'] *= 6.5/60/2
df = df[df.cart_sep < 1.0]
#df = df.query('0.55 < cart_sep < 0.65')
g = sns.JointGrid(x='del_theta', y='cart_sep', data=df, size=7, ratio=2)
g.plot_joint(plt.scatter, s=1.5, marker='.')
g.ax_marg_x.hist(df.del_theta, bins=100)
g.ax_marg_y.hist(df.cart_sep, bins=100, orientation='horizontal')
g.set_axis_labels(xlabel=r'$\Delta \theta$ (degrees)', ylabel=r'Separation ($\mu$m)')
plt.setp(g.ax_marg_x.get_yticklabels(), visible=True)
plt.setp(g.ax_marg_y.get_xticklabels(), visible=True)
plt.show()
If the particles always passed eachother at optical binding separations then I would expect to see horizontal lines accross $\Delta \theta = 0$ meaning that there is a preferred separation as two particles pass one another.
If you squint at the graph there is the posibility of seeing some horizontal lines but to me it looks like there is no real trend.
df = giant_df.copy()
df = df.dropna(axis=0, subset=['del_theta'])
df = df[df['track id'] < df['theta_nn_id']]
df = df.query('-20 < del_theta < 20')
df = df.query('65 < r < 105')
g = sns.JointGrid(x='del_theta', y='r', data=df, size=7, ratio=2)
g.plot_joint(plt.scatter, s=1.5, marker='.', alpha=0.4)
g.ax_marg_x.hist(df.del_theta, bins=100)
g.ax_marg_y.hist(df.r, bins=100, orientation='horizontal')
g.set_axis_labels(xlabel=r'$\Delta \theta$ (degrees)', ylabel=r'r (pixels)')
g.ax_marg_x.set_title('All Mosaic Data')
plt.setp(g.ax_marg_x.get_yticklabels(), visible=True)
plt.setp(g.ax_marg_y.get_xticklabels(), visible=True)
plt.show()
This graph I intended to help inform me about if my designation of the two cases was correct, that is:
If there was a preference I would expect the at $\Delta \theta$=0 the position in r would have increased probability density along the average r. In the scatter plot above there is some evidence of increased probability at $\Delta \theta$=0 for r at the average r but it doesn't seem to be really clear.